package myapp.camera;

import java.io.IOException;
import java.util.List;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
	
	SurfaceHolder mHolder;
	public Camera camera = null;
	private CameraCallback callback = null;
	private int degreeOrientation = 90;
	public CameraPreview(Context context) {
		super(context);
		// Install a SurfaceHolder.Callback so we get notified when the
				// underlying surface is created and destroyed.
		mHolder = getHolder();
		mHolder.addCallback(this);
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int w,
			int h) {
		// Now that the size is known, set up the camera parameters and begin
		// the preview.
		Camera.Parameters parameters = camera.getParameters();
		//parameters.setPreviewSize(w, h);
	    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

	    if (previewSizes.size() != 0)
	    {
	    	Camera.Size previewSize = previewSizes.get(0);

	    	parameters.setPreviewSize(previewSize.width, previewSize.height);
	    	//android.util.Log.i("CameraW_surfaceChanged", String.valueOf(previewSize.width));
	    	//android.util.Log.i("CameraH_surfaceChanged", String.valueOf(previewSize.height));
	    	
			camera.setParameters(parameters);
	    }

	    camera.stopPreview();
		try
		{
			/*if (w < h)
				camera.setDisplayOrientation(90);
			else
				camera.setDisplayOrientation(0);*/
	    	camera.setDisplayOrientation(degreeOrientation);
		}
		catch (Exception e)
		{
			android.util.Log.i("CameraH_surfaceChanged", e.toString());
		}
		camera.startPreview();
	}
	
	public void setDegreeOrientation(int rotation)
	{		 
	     switch (rotation) {
         case Surface.ROTATION_0: degreeOrientation = 90; break;
         case Surface.ROTATION_90: degreeOrientation = 0; break;
         case Surface.ROTATION_180: degreeOrientation = 270; break;
         case Surface.ROTATION_270: degreeOrientation = 180; break;
	     }
	}

	
	public void surfaceCreated(SurfaceHolder holder) {
		// The Surface has been created, acquire the camera and tell it where
		// to draw.
		
		
		try {
			camera = Camera.open();
			camera.setPreviewDisplay(holder);
			camera.setPreviewCallback(new Camera.PreviewCallback() {
			
				public void onPreviewFrame(byte[] data, Camera camera) {
					if(null != callback) callback.onPreviewFrame(data, camera);
				}
			});
		} catch (IOException e) {
			camera.release();
			camera = null;
			e.printStackTrace();
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// Surface will be destroyed when we return, so stop the preview.
		// Because the CameraDevice object is not a shared resource, it's very
		// important to release it when the activity is paused.
		if (camera != null)
		{
			camera.stopPreview();
			camera.setPreviewCallback(null);
			camera.release();
			camera = null;
		}
		Log.d("CameraPreview", "Surface Destroyed!");
	}
	
	public void DestroyCamera()
	{
		if (camera != null)
		{
			camera.stopPreview();
			camera.setPreviewCallback(null);
			camera.release();
			camera = null;
		}
		Log.d("CameraPreview", "DestroyCamera!");
	}
	

	public void setCallback(CameraCallback callback){
		this.callback = callback;
	}
	
	public void startPreview(){
		camera.startPreview();
	}
	
	public void startTakePicture(){
		camera.autoFocus(new AutoFocusCallback() {
			public void onAutoFocus(boolean success, Camera camera) {
				takePicture();
			}
		});
	}
	public void takePicture() {
		camera.takePicture(
				new ShutterCallback() {
					public void onShutter(){
						if(null != callback) callback.onShutter();
					}
				},
				new PictureCallback() {
			
					public void onPictureTaken(byte[] data, Camera camera){
						if(null != callback) callback.onRawPictureTaken(data, camera);
					}
				},
				new PictureCallback() {
					
					public void onPictureTaken(byte[] data, Camera camera){
						if(null != callback) callback.onJpegPictureTaken(data, camera);
					}
				});
	}
	
}
